abstract class Block {
  float x, y, w, h;
  float health;
  Body body;
  PImage img;
  
  Block(float x, float y, float w, float h, float health, float angularDamping, float density, float friction, float restitution) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.health = health;
    
    BodyDef bd = new BodyDef();
    // Set its position
    bd.position = box2d.coordPixelsToWorld(x, y);
    bd.type = BodyType.DYNAMIC;
    bd.angularDamping = angularDamping;
    this.body = box2d.world.createBody(bd);

    PolygonShape ps = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(this.w / 2);
    float box2dH = box2d.scalarPixelsToWorld(this.h / 2);
    ps.setAsBox(box2dW, box2dH);
    
    FixtureDef fd = new FixtureDef();
    fd.shape = ps;
    // Parameters that affect physics
    fd.density = density;
    fd.friction = friction;
    fd.restitution = restitution;
    
    // Attach fixture to body
    this.body.createFixture(fd);
    this.body.setUserData(this);
  }
  
  abstract void draw();
  
  boolean isOutOfHealth() {
    return this.health <= 0;
  }
  
  void destroy() {
    box2d.destroyBody(this.body);
  }
}

class Wood extends Block {
  Wood(float x, float y) {
    super(x, y, 96, 12, 1000, 3, 1, 1000, 0.3);
    super.img = loadImage("wood.png");
  }
  
  void draw() {
    Vec2 position = box2d.getBodyPixelCoord(this.body);
    float angle = this.body.getAngle();
    pushMatrix();
    translate(position.x, position.y);
    rotate(-angle);
    image(super.img, 0, 0, super.w, super.h);
    popMatrix();
  }
}

class Stone extends Block {
  Stone(float x, float y) {
    super(x, y, 24, 48, 2000, 3, 2, 1000, 0.3);
    super.img = loadImage("stone.png");
  }
  
  void draw() {
    Vec2 position = box2d.getBodyPixelCoord(this.body);
    float angle = this.body.getAngle();
    pushMatrix();
    translate(position.x, position.y);
    rotate(-angle);
    image(super.img, 0, 0, super.w, super.h);
    popMatrix();
  }
}
